from django.shortcuts import render

# Create your views here.
from rest_framework.response import Response
from rest_framework.views import APIView

from cats.serializers import CartViewsSerializer, CartListSerializer, CartDeleteSerializer, CartViewsSelectionSerializer
from django_redis import get_redis_connection
import base64,pickle

from goods.models import SKU


class CartViews(APIView):
    """
    购物车增删改查
    """
    # 因为用户未登录的情况下还要保存数据 ，而post 方法前段携带jwt,会在调用post 之前进行验证
    def perform_authentication(self, request):
        pass
    def post(self,request):
        # 获取前端数据
        data = request.data
        # 验证数据
        ser = CartViewsSerializer(data=data)
        ser.is_valid()
        print(ser.errors)
        # 获取验证后的数据
        sku_id = ser.validated_data["sku_id"]
        count= ser.validated_data["count"]
        selected = ser.validated_data["selected"]

        # 判断用户是否登录
        try:
            user = request.user
        except:
            user = None
        if user is not None:
            # 如果用户登录
            # 1.建立连接
            coon = get_redis_connection("cart")
            # 2.写入hash
            coon.hincrby("cart_%s"%user.id,sku_id,count)
             # 3.写入set
            if selected:
                coon.sadd("cart_selected_%s"%user.id,sku_id)
                 #4. 返回结果
                return Response({"message":"ok"})
        else:
            response = Response({'message': 'ok'})
            # 获取cookie
            cart_cookie = request.COOKIES.get("cart_cookie",None)
            # 判断原先是否写过cookie
            if cart_cookie:
                # 如果获取到cookie 先进行解密
              cart = pickle.loads(base64.b64decode(cart_cookie))
            else:
              cart ={}
            # 判断sku_id 是否存在
            sku = cart.get(sku_id)
            if sku:
                # 如果存在累加
                count += int(sku["count"])
            # 写入新数据
            cart[sku_id]={
                "count":count,
                "selected":selected
            }
            # 加密
            cart_cookie = base64.b64encode(pickle.dumps(cart))
            # 写入cookie
            response.set_cookie("cart_cookie", cart_cookie ,max_age=60*60*24)
            # 结果返回
            return response

    def get(self,request):
        # 判断用户是否登录
        try:
            user = request.user
        except:
            user = None
        if user is not None:
            # 如果用户登录
            # 1.建立连接
            coon = get_redis_connection("cart")
            # 2.写入hash
            sku_id_count = coon.hgetall("cart_%s" % user.id)
            selected = coon.smembers("cart_selected_%s" % user.id)
            # 4. 返回结果
            cart = {}

            for sku_id,count in sku_id_count.items():
                cart[int(sku_id)] = {
                    "count":int(count),
                    "selected":sku_id in selected
                }
        else:
            # 获取cookie
            cart_cookie = request.COOKIES.get("cart_cookie", None)
            # 判断原先是否写过cookie
            if cart_cookie:
                # 如果获取到cookie 先进行解密
                cart = pickle.loads(base64.b64decode(cart_cookie))
            else:
                cart = {}
        sku_ids = cart.keys()
        # 判断sku_id 是否在范围内
        skus = SKU.objects.filter(id__in=sku_ids)

        for sku in skus:
            sku.count = cart[sku.id]["count"]
            sku.selected = cart[sku.id]["selected"]

        ser = CartListSerializer(skus,many=True)

        return Response(ser.data)


    def put(self, request):
        # 获取前端数据
        data = request.data
        # 验证数据
        ser = CartViewsSerializer(data=data)
        ser.is_valid()
        print(ser.errors)
        # 获取验证后的数据
        sku_id = ser.validated_data["sku_id"]
        count = ser.validated_data["count"]
        selected = ser.validated_data["selected"]

        # 判断用户是否登录
        try:
            user = request.user
        except:
            user = None
        if user is not None:
            # 如果用户登录
            # 1.建立连接
            coon = get_redis_connection("cart")
            # 2.更新hash
            coon.hset("cart_%s" % user.id, sku_id, count)
            # 3.写入set
            if selected:
                coon.sadd("cart_selected_%s" % user.id, sku_id)
            else:
                coon.srem("cart_selected_%s" % user.id, sku_id)
                # 4. 返回结果
            return Response({"count":count})
        else:
            response = Response({"count":count,"selected":selected})
            # 获取cookie
            cart_cookie = request.COOKIES.get("cart_cookie", None)
            # 判断原先是否写过cookie
            if cart_cookie:
                # 如果获取到cookie 先进行解密
                cart = pickle.loads(base64.b64decode(cart_cookie))
            else:
                cart = {}

            # 写入新数据
            cart[sku_id] = {
                "count": count,
                "selected": selected
            }
            # 加密
            cart_cookie = base64.b64encode(pickle.dumps(cart))
            # 写入cookie
            response.set_cookie("cart_cookie", cart_cookie, max_age=60 * 60 * 24)
            # 结果返回

            return response

    def delete(self,request):
        # 获取前端数据
        data = request.data
        # 验证数据
        ser = CartDeleteSerializer(data=data)
        ser.is_valid()
        print(ser.errors)
        # 获取验证后的数据
        sku_id = ser.validated_data["sku_id"]

        # 判断用户是否登录
        try:
            user = request.user
        except:
            user = None
        if user is not None:
            # 如果用户登录
            # 1.建立连接
            coon = get_redis_connection("cart")
            # 2.写入hash
            coon.hdel("cart_%s"%user.id,sku_id)
            coon.srem("cart_selected_%s"%user.id,sku_id)
                 #4. 返回结果
            return Response({"message":"ok"})
        else:
            response = Response({'message': 'ok'})
            # 获取cookie
            cart_cookie = request.COOKIES.get("cart_cookie",None)
            if cart_cookie:
                # 写入过，解密
                cart = pickle.loads(base64.b64decode(cart_cookie))
                # 删除数据
                if sku_id in cart.keys():
                    del cart[sku_id]


                # 加密
                cart_cookie = base64.b64encode(pickle.dumps(cart))
                # 写入cookie
                response.set_cookie("cart_cookie", cart_cookie ,max_age=60*60*24)
            # 结果返回
            return response


class CartSelectionViews(APIView):
    """
    购物车全选状态
    """
    def perform_authentication(self, request):
        pass
    def put(self,request):
        # 获取前端数据
        data = request.data
        # 验证数据
        ser = CartViewsSelectionSerializer(data=data)
        ser.is_valid()
        print(ser.errors)
        # 获取验证后的数据

        selected = ser.validated_data["selected"]

        # 判断用户是否登录
        try:
            user = request.user
        except:
            user = None
        if user is not None:
            # 如果用户登录
            # 1.建立连接
            coon = get_redis_connection("cart")
            # 2.写入hash
            sku_id_count = coon.hgetall("cart_%s" % user.id)
            skuid = sku_id_count.keys()  #列表拆包

            # 3.写入set
            if selected:
                coon.sadd("cart_selected_%s" % user.id,*skuid)
            else:
                coon.srem("cart_selected_%s" % user.id,*skuid)
                # 4. 返回结果
            return Response({"selected":selected})
        else:
            response = Response({"selected":selected})
            # 获取cookie
            cart_cookie = request.COOKIES.get("cart_cookie", None)
            # 判断原先是否写过cookie
            if cart_cookie:
                # 如果获取到cookie 先进行解密
                cart = pickle.loads(base64.b64decode(cart_cookie))

                for skuids,data in cart.items():
                    data["selected"] = selected

                # 加密
                cart_cookie = base64.b64encode(pickle.dumps(cart))
                # 写入cookie
                response.set_cookie("cart_cookie", cart_cookie, max_age=60 * 60 * 24)
                # 结果返回
                return response